
#region Imported Namespaces
using System;
using System.Collections;
using System.Configuration;
using System.Web;
using System.Web.UI;
using HttpSessionState = System.Web.SessionState.HttpSessionState;
#endregion

namespace PHSRAG.Insight21.Policy
{
	#region Enum CacheLocation
	/// <summary>
	/// The CacheLocation enumeration defines where an object can be cached, it at all.
	/// </summary>
	public enum CacheLocation
	{
		/// <summary>Caching is disabled</summary>
		None,
		
		/// <summary>Caching is done through ViewState</summary>
		ViewState,
		
		/// <summary>Caching is done through Session</summary>
		Session,

		/// <summary>Caching is done through Application</summary>
		Application,

        /// <summary>Caching is done through Framework Cache Object</summary>
		FrameWorkCacheObject
	}
	#endregion

	#region Interface ICachePolicy
	/// <summary>
	/// The ICachePolicy interface defines the interaction between objects which implement the interface and their
	/// clients.
	/// </summary>
	public interface ICachePolicy
	{
		#region Properties
		/// <summary>
		/// Get the location where an object can be cached. Interface implementors provide the body.
		/// </summary>
		CacheLocation	Location	{ get; }
		#endregion

		#region Methods
		/// <summary>
		/// Cache an object using the prevalent caching policy. Interface implementors provide the body.
		/// </summary>
		/// <param name="key">Key under which the object is to be cached</param>
		/// <param name="o">Object to cache</param>
		void	Cache(string key, object o);

		/// <summary>
		/// Get the cached object using the prevalent caching policy. Interface implementors provide the body.
		/// </summary>
		/// <param name="key">Key under which the object is cached</param>
		/// <returns>Reference to the object cached under the specified key</returns>
		object	GetCachedObject(string key);

      /// <summary>
      /// Purge all objects cached using this cache policy. Interface implementors provide the body.
      /// </summary>
      /// <param name="moduleKey">Key discriminator for the module</param>
      /// <param name="excludeKeys">Keys to be excluded from the purge</param>
      void	Purge(string moduleKey, params string[] excludeKeys);

		/// <summary>
		/// Uncache an object using the prevalent caching policy.  Interface implementors provide the body.
		/// </summary>
		/// <param name="key">Key under which the object is cached</param>
		void	UnCache(string key);
		#endregion
	}
	#endregion

	#region Class NullCachePolicy
	/// <summary>
	/// The NullCachePolicy class does not support caching at all.
	/// </summary>
	public class NullCachePolicy : ICachePolicy
	{
		#region ICachePolicy Members
		/// <summary>
		/// This cache policy returns none since caching is not enabled.
		/// </summary>
		public CacheLocation	Location	{ get { return CacheLocation.None; } }

		/// <summary>
		/// This cache policy does not cache anything at all.
		/// </summary>
		/// <param name="key">Key under which the object is to be cached</param>
		/// <param name="o">Object to cache</param>
		public void Cache(string key, object o)
		{
		}

		/// <summary>
		/// This cache policy does not cache anything at all, and hence this method always returns null.
		/// </summary>
		/// <param name="key">Key under which the object is cached</param>
		/// <returns>Reference to the object cached under the specified key</returns>
		public object GetCachedObject(string key)
		{
			return null;
		}

		/// <summary>
		/// This cache policy does not cache anything at all, and hence this method does nothing.
		/// </summary>
		/// <param name="moduleKey">Key discriminator for the module</param>
		/// <param name="excludeKeys">Keys to be excluded from the purge</param>
		public void Purge(string moduleKey, params string[] excludeKeys)
		{
		}

		/// <summary>
		/// This cache policy does not cache anything at all, and hence this method does nothing.
		/// </summary>
		/// <param name="key">Key under which the object is cached</param>
		public void UnCache(string key)
		{
		}
		#endregion
	}

	#endregion

	#region Class SessionCachePolicy
	/// <summary>
	/// The SessionCachePolicy uses the HttpSessionState to carryout caching operations.
	/// </summary>
	public class SessionCachePolicy : ICachePolicy
	{
		#region Instance Variables
		private HttpSessionState	session;
		#endregion

		#region Constructor
		/// <summary>
		/// Create an instance of the SessionCachePolicy wherein the specified session reference is used.
		/// </summary>
		/// <param name="session">Session to use for caching operations</param>
		public SessionCachePolicy(HttpSessionState session)
		{
			this.session = session;
		}
		#endregion

		#region ICachePolicy Members
		/// <summary>
		/// Get the session object used for caching operations.
		/// </summary>
		public CacheLocation	Location	{ get { return CacheLocation.Session; } }

		/// <summary>
		/// Cache an object using a key in the session.
		/// </summary>
		/// <param name="key">Key under which the object is cached</param>
		/// <param name="o">Ojbect to cache</param>
		public void Cache(string key, object o)
		{
			session[key] = o;
		}

		/// <summary>
		/// Get the cached object from the session stored under a specific key.
		/// </summary>
		/// <param name="key">Key under which the object is cached</param>
		/// <returns>Object from the cache</returns>
		public object GetCachedObject(string key)
		{
			return session[key];
		}

		/// <summary>
		/// Remove all objects stored in the cache based on the key.
		/// </summary>
		/// <param name="moduleKey">Key discriminator for the module</param>
		/// <param name="excludeKeys">Keys to be excluded from the purge</param>
		public void Purge(string moduleKey, params string[] excludeKeys)
		{
			//$ For now (during dev, only Session_End purge is taken care of.
			if (moduleKey == null)	// True only when invoked by Session_End.
			{
//				System.Diagnostics.Trace.WriteLine(string.Format("ModuleKey: {0}", moduleKey));

				ArrayList keys = new ArrayList(session.Keys.Count);
				keys.AddRange(session.Keys);
			
				if (excludeKeys.Length > 0)
					foreach (string excludeKey in excludeKeys)
					{
						System.Diagnostics.Trace.WriteLine(string.Format("ExcludeKey: {0}", excludeKey));
						keys.Remove(excludeKey);
					}

				Purge(keys);
			}
		}

		/// <summary>
		/// Remove any object stored in the cache under a specific key.
		/// </summary>
		/// <param name="key">Key under which the object is cached</param>
		public void UnCache(string key)
		{
			session.Remove(key);
		}
		#endregion

		#region Private Methods
		private void Purge(ArrayList keys)
		{
			foreach (string key in keys)
			{
				System.Diagnostics.Trace.WriteLine(string.Format("Purging: {0}", key));
				try
				{
					IDisposable disposable = session[key] as IDisposable;
					if (disposable != null)
						disposable.Dispose();
					session[key] = null;
				}
				catch
				{
				}
				finally
				{
					session.Remove(key);
				}
			}
		}
		#endregion
	}
	#endregion

	#region Class ViewStateCachePolicy
	/// <summary>
	/// The ViewStateCachePolicy uses the ViewState to carryout caching operations.
	/// </summary>
	public class ViewStateCachePolicy : ICachePolicy
	{
		#region Instance Variables
		private StateBag	viewState;
		#endregion

		#region Constructor
		/// <summary>
		/// Create an instance of the ViewStateCachePolicy class wherein the specified ViewState reference is used.
		/// </summary>
		/// <param name="viewState">ViewState to use for caching operations</param>
		public ViewStateCachePolicy(StateBag viewState)
		{
			this.viewState = viewState;
		}
		#endregion

		#region ICachePolicy Members
		/// <summary>
		/// Get the session object used for caching operations.
		/// </summary>
		public CacheLocation	Location	{ get { return CacheLocation.ViewState; } }

		/// <summary>
		/// Cache an object using a key in the ViewState.
		/// </summary>
		/// <param name="key">Key under which the object is cached</param>
		/// <param name="o">Ojbect to cache</param>
		public void Cache(string key, object o)
		{
			viewState[key] = o;
		}

		/// <summary>
		/// Get the cached object from the ViewState stored under a specific key.
		/// </summary>
		/// <param name="key">Key under which the object is cached</param>
		/// <returns>Object from the cache</returns>
		public object GetCachedObject(string key)
		{
			return viewState[key];
		}

		/// <summary>
		/// Remove all objects stored in the cache based on the key.
		/// </summary>
		/// <param name="moduleKey">Key discriminator for the module</param>
		/// <param name="excludeKeys">Keys to be excluded from the purge</param>
		public void Purge(string moduleKey, params string[] excludeKeys)
		{
		}

		/// <summary>
		/// Remove any object stored in the cache under a specific key.
		/// </summary>
		/// <param name="key">Key under which the object is cached</param>
		public void UnCache(string key)
		{
			viewState.Remove(key);
		}
		#endregion
	}
	#endregion

	#region Class ApplicationCachePolicy
	/// <summary>
	/// The ApplicationCachePolicy uses the HttpApplicationState to carryout caching operations
	/// </summary>
	public class ApplicationCachePolicy : ICachePolicy
	{
		#region Instance Variables
		private HttpApplicationState application;
		#endregion

		#region Constructor
		/// <summary>
		/// Create an instance of the ApplicationCachePolicy wherein the specified application reference is used.
		/// </summary>
		/// <param name="application">Application to use for caching operations</param>
		public ApplicationCachePolicy(HttpApplicationState application)
		{
			this.application = application;
		}
		#endregion

		#region ICachePolicy Members
		/// <summary>
		/// Get the application object used for caching operations.
		/// </summary>
		public CacheLocation	Location	{ get { return CacheLocation.Application; } }

		/// <summary>
		/// Cache an object using a key in the application.
		/// </summary>
		/// <param name="key">Key under which the object is cached</param>
		/// <param name="o">Ojbect to cache</param>
		public void Cache(string key, object o)
		{
			application[key] = o;
		}

		/// <summary>
		/// Get the cached object from the application stored under a specific key.
		/// </summary>
		/// <param name="key">Key under which the object is cached</param>
		/// <returns>Object from the cache</returns>
		public object GetCachedObject(string key)
		{
			return application[key];
		}

		/// <summary>
		/// Remove all objects stored in the cache based on the key.
		/// </summary>
		/// <param name="moduleKey">Key discriminator for the module</param>
		/// <param name="excludeKeys">Keys to be excluded from the purge</param>
		public void Purge(string moduleKey, params string[] excludeKeys)
		{
		}

		/// <summary>
		/// Remove any object stored in the cache under a specific key.
		/// </summary>
		/// <param name="key">Key under which the object is cached</param>
		public void UnCache(string key)
		{
			application.Remove(key);
		}
		#endregion
	}
	#endregion

    #region Class FrameWorkCachePolicy
    /// <summary>
    /// The SessionCachePolicy uses the HttpSessionState to carryout caching operations.
    /// </summary>
    public class FrameWorkCachePolicy : ICachePolicy
    { 
        #region Constructor
        /// <summary>
        /// Create an instance of the SessionCachePolicy wherein the specified session reference is used.
        /// </summary>
        /// <param name="session">Session to use for caching operations</param>
        public FrameWorkCachePolicy()
        {
        }
        #endregion

        #region ICachePolicy Members
        /// <summary>
        /// Get the session object used for caching operations.
        /// </summary>
        public CacheLocation Location { get { return CacheLocation.FrameWorkCacheObject; } }

        /// <summary>
        /// Cache an object using a key 
        /// </summary>
        /// <param name="key">Key under which the object is cached</param>
        /// <param name="o">Object to cache</param>
        public void Cache(string key, object o)
        {
            string CacheDuration = ConfigurationManager.AppSettings["PageCacheTimeoutMinutes"];
            HttpContext.Current.Cache.Insert(key, o, null, DateTime.Now.AddMinutes(Convert.ToInt32(CacheDuration)), TimeSpan.Zero, 
                System.Web.Caching.CacheItemPriority.Normal, null);
        }

        /// <summary>
        /// Get the cached object from the Cache object stored under a specific key.
        /// </summary>
        /// <param name="key">Key under which the object is cached</param>
        /// <returns>Object from the cache</returns>
        public object GetCachedObject(string key)
        {
            return HttpContext.Current.Cache.Get(key);
        }

        /// <summary>
        /// Remove all objects stored in the cache based on the key.
        /// </summary>
        /// <param name="moduleKey">Key discriminator for the module</param>
        /// <param name="excludeKeys">Keys to be excluded from the purge</param>
        public void Purge(string moduleKey, params string[] excludeKeys)
        {
        }

        /// <summary>
        /// Remove any object stored in the cache under a specific key.
        /// </summary>
        /// <param name="key">Key under which the object is cached</param>
        public void UnCache(string key)
        {
            HttpContext.Current.Cache.Remove(key);
        }
        #endregion
    }
    #endregion
}

// --- EOF ---
